<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
  <head>
    <title>Writing R Packages</title>
    <meta charset="utf-8" />
    <meta name="author" content="Daniel D. Sjoberg  Memorial Sloan Kettering Cancer Center Department of Epidemiology and Biostatistics" />
    <meta name="date" content="2019-03-28" />
    <link href="libs/remark-css/ninjutsu.css" rel="stylesheet" />
    <link href="libs/remark-css/default.css" rel="stylesheet" />
    <link href="libs/remark-css/default-fonts.css" rel="stylesheet" />
    <link rel="stylesheet" href="my-theme.css" type="text/css" />
  </head>
  <body>
    <textarea id="source">
class: center, middle, inverse, title-slide

# Writing R Packages
## with Rstudio, {usethis}, and {roxygen2}
### Daniel D. Sjoberg<br/><br/>Memorial Sloan Kettering Cancer Center<br/>Department of Epidemiology and Biostatistics
### March 28, 2019

---




class: center, middle
&lt;img src="images/RStudio-Logo-Flat.png" width = "75%"&gt;
.pull-left[.center[
&lt;img src="images/usethis logo.png"&gt;
]]
.pull-right[.center[
&lt;img src="images/roxygen2 logo 3.png" width = "52%"&gt;
]]

---
background-image: url(images/hex_stickers_blurred3.png)
background-size: contain
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- _**R Package Structure**_

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Package Structure
.xlarge[.pull-left[
An R package needs 3 components

1. DESCRIPTION file&lt;/br&gt;&lt;/br&gt;

2. NAMESPACE file&lt;/br&gt;&lt;/br&gt;

3. R code folder
]]
.pull-right[
&lt;img src="images/basic package structure.PNG"&gt;
]

---
# Package Structure
.xlarge[.pull-left[
An R package needs 3 components

1. _**DESCRIPTION file**_&lt;/br&gt;&lt;/br&gt;

2. NAMESPACE file&lt;/br&gt;&lt;/br&gt;

3. R code folder
]]
.pull-right[
```
Package: mypackage
Title: What The Package Does (one line)
Version: 0.1
Authors@R: person(
  "First", "Last", 
  email = "first.last@example.com",
  role = c("aut", "cre"))
Description: What the package does 
  (one paragraph)
Depends: R (&gt;= 3.5)
Imports: dplyr
License: What license is it under?
LazyData: true
```
* store metadata about the package

* list dependencies

* specify version number of package
]

---
# Package Structure
.xlarge[.pull-left[
An R package needs 3 components

1. DESCRIPTION file&lt;/br&gt;&lt;/br&gt;

2. _**NAMESPACE file**_&lt;/br&gt;&lt;/br&gt;

3. R code folder
]]
.pull-right[

```r
# Generated by roxygen2: do not edit by hand

export(tbl_regression)
export(tbl_summary)
export(tbl_uvregression)
importFrom(glue,glue)
importFrom(knitr,knit_print)
importFrom(magrittr,"%&gt;%")
```

* {roxygen2} will take care of this for you!

* lists functions that will be exported by your package

* lists functions imported from other packages
]

---
# Package Structure
.xlarge[.pull-left[
An R package needs 3 components

1. DESCRIPTION file&lt;/br&gt;&lt;/br&gt;

2. NAMESPACE file&lt;/br&gt;&lt;/br&gt;

3. _**R code folder**_
]]
.pull-right[
* R folder contains R code for each function in your package
  - typically, one code file for each exported function (although not required)
  
  - e.g. `myfirstfunction.R`
  
* also contains code for helper or utility functions
  - these functions are not exported, that is, not available to users of the package
  
  - utility function files begin with utils- prefix 
  
  - e.g. `utils-myfirstfunction.R`
]

---
# Package Structure
.xlarge[.pull-left[
An R package needs 3 components

1. DESCRIPTION file&lt;/br&gt;&lt;/br&gt;

2. NAMESPACE file&lt;/br&gt;&lt;/br&gt;

3. R code folder
]]
.large[.pull-right[
The {usethis} package has functions that create the package structure for you

After any function in {usethis} is run, it prints additional information into the console. READ AND FOLLOW THE DIRECTIONS!
- lists files created
- lists files modified
- lists user instructions

{usethis} makes package development a breeze
]]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- _**Getting Started**_

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- `usethis::create_package()`

- `usethis::use_package_doc()`

- `usethis::use_git()`

- `usethis::use_github()`
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- _**`usethis::create_package()`**_

- `usethis::use_package_doc()`

- `usethis::use_git()`

- `usethis::use_github()`
]

.pull-right[
```
&gt; usethis::create_package("~/myPackage")
✔ Setting active project to '~/myPackage'
✔ Creating 'R/'
✔ Creating 'man/'
✔ Writing 'DESCRIPTION'
✔ Writing 'NAMESPACE'
✔ Writing 'myPackage.Rproj'
✔ Adding '.Rproj.user' to '.gitignore'
✔ Adding '^myPackage\\.Rproj$', '^\\.Rproj\\.user$' 
   to '.Rbuildignore'
✔ Opening new project 'myPackage' in RStudio
```

* Create package folder and a skeleton of the folder structure
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- `usethis::create_package()`

- _**`usethis::use_package_doc()`**_

- `usethis::use_git()`

- `usethis::use_github()`
]

.pull-right[
```
&gt; usethis::use_package_doc()
✔ Writing 'R/myPackage-package.R'
```

'R/myPackage-package.R' contents
```
#' @keywords internal
"_PACKAGE"
```

* writes a basic documentation file for you package

* we will add more to this later
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- `usethis::create_package()`

- `usethis::use_package_doc()`

- _**`usethis::use_git()`**_

- `usethis::use_github()`
]

.pull-right[
```
&gt; usethis::use_git()
✔ Initialising Git repo
✔ Adding '.Rhistory', '.RData' to '.gitignore'
OK to make an initial commit of 6 files?
1: Negative
2: Not now
3: Yeah

Selection: 3
✔ Adding files and committing
```
* create a git repository

* commit existing files to the repo
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- `usethis::create_package()`

- `usethis::use_package_doc()`

- `usethis::use_git()`

- _**`usethis::use_github()`**_
]

.pull-right[
```
&gt; usethis::use_github()
● Check title and description
  Name:        myPackage
  Description: What the Package Does (One Line)
Are title and description ok?
1: No
2: Nope
3: Yeah

Selection: 3
✔ Creating GitHub repository
✔ Adding GitHub remote
✔ Adding GitHub links to DESCRIPTION
✔ Setting URL field in DESCRIPTION to 
  'https://github.com/ddsjoberg/myPackage'
✔ Setting BugReports field in DESCRIPTION to 
  'https://github.com/ddsjoberg/myPackage/issues'
✔ Pushing to GitHub and setting 
  remote tracking branch
```
]

---
# Getting Started

.pull-left[
A few functions to get you started with a new package

- `usethis::create_package()`

- `usethis::use_package_doc()`

- `usethis::use_git()`

- _**`usethis::use_github()`**_
]

.pull-right[
* THIS ONLY WORKS IF YOU'VE PREVIOUSLY CONFIGURED THE `use_github()` FUNCTION

* recommend you setup Rstudio to play nicely with GitHub.  Read *Happy Git and GitHub for the useR* for details (https://happygitwithr.com/)

* you can create your GitHub repo manually and add the package contents if you haven't yet configured RStudio and GitHub
  - remember to update the url and bug reports url in the DESCRIPTION file to match the GitHub repo location
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- _**Adding Functions**_

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Adding Functions

`usethis::use_r()` 
- creates a new code file for you write your function

- places file correctly in the `R` folder

- the new file is entirely blank

```
&gt; usethis::use_r("my_mean")
● Modify 'R/my_mean.R'
```

---
# Adding Functions

Let's write our first function


```r
my_mean &lt;- function(x) {
  mean(na.omit(x))
}
```
--
For EVERY non-base R function you need to either *import* the function, or use `::` to reference the function


```r
my_mean &lt;- function(x) {
  mean(stats::na.omit(x))
}
```

We will now use {roxygen2} comments in our code to document our new function (aka write the help file)!

---
# Adding Functions: Documentation

* R function help files (\*.Rd) are saved in the *man* folder

* the *man* folder already exists courtesy of `usethis::create_package()`

* R processes the \*.Rd files to create plain text, PDF, and HTML versions of the help files

* the code in \*.Rd files looks somewhat like LaTeX: it's verbose and cumbersome to write

* we will automate the creation of these files with {roxygen2} comments

* by automating, we link the function code to the documentation 

* this helps keep the documentation up to date

```
&gt; usethis::use_roxygen_md()
✔ Setting Roxygen field in DESCRIPTION to 'list(markdown = TRUE)'
✔ Setting RoxygenNote field in DESCRIPTION to '6.1.1'
● Run `devtools::document()`
```

---
# Adding Functions: Documentation

* roxygen comments appear above a function

* roxygen comment lines always begins with `#'`

* two common roxygen tags
  - `@param` used to document a function argument
  - `@export` tells roxygen to export the function when the package is built


```r
#' The first line is the title
#'
#' The second section is a longer description of the function.
#' This can go on for multiple lines.
#' 
#' @param x numeric vector
#' @export
my_mean &lt;- function(x) {
  mean(stats::na.omit(x))
}
```

---
# Adding Functions: Documentation

* other notable roxygen tags
  - `@seealso` list related references (typically used to reference related functions)
  - `@family` similar to `@seealso`, but creates a list of "see also" functions that belong to the same family
  - `@examples` add examples to function help file
  - `@author` list author(s) of the function
  - `@return` specify the returned object 

* link to other functions in help file
  - function in the same package `\code{\link{my_mean}}`
  - function in another package `\code{\link[base]{mean}}`

* additional resources
  - *Rd* vignette in {roxygen2} package
  - Blog post http://kbroman.org/pkg_primer/pages/docs.html

---
# Adding Functions: Documentation

.pull-left[

```r
#' The first line is the title
#'
#' The second section is a longer 
#' description of the function.
#' This can go on for multiple lines.
#' 
#' @param x numeric vector
#' @export
#' @seealso \code{\link[base]{mean}}
#' @author Daniel D. Sjoberg
#' @examples
#' my_mean(1:5)
my_mean &lt;- function(x) {
  mean(stats::na.omit(x))
}
```
]
.pull-right[
&lt;img src="images/my_mean help.PNG"&gt;
]

---
# Adding Functions: Rstudio Build Tab

&lt;img src="images/build tab.PNG"&gt;

**Document** each time you update roxygen comments

  
---
# Adding Functions
.pull-left[
* new function calculates mean of every column in a data frame

* use the `map()` function in the {purrr} package

* use `::` to refer to the function: `purrr::map()`

* document that our package now depends on {purrr}

* `usethis::use_package("purrr")`

```
&gt; usethis::use_package("purrr")
✔ Setting active project to '~/myPackage'
✔ Adding 'purrr' to Imports field 
  in DESCRIPTION
● Refer to functions with `purrr::fun()`
```
]
.pull-right[
`DESCRIPTION` (truncated)
```
Imports: 
    purrr
```
&lt;hr&gt;

```r
df_mean &lt;- function(data) {
  purrr::map(data, my_mean)
}
```
```
&gt; df_mean(mtcars)
$mpg
[1] 20.09062

$cyl
[1] 6.1875

$disp
[1] 230.7219
```
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- _**Build your Package**_

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Build your Package: Rstudio Build Tab

&lt;img src="images/build tab.PNG"&gt;
* **Document** each time you update roxygen comments
* **Install and Restart** each time you update R code
* **Check** 

---
# Build your Package

What is checked?  

--
So much!  Here's a very abbreviated list
.pull-left[
* package structure
  - hidden files/folders
  - portable file names
  - executable files
  - package subdirectories
  - left-over files

* DESCRIPTION/NAMESPACE file    
  - package dependencies
  - files exist
  - NAMESPACE parses properly
]
.pull-right[
* R code
  - non-ASCII characters
  - syntax errors
  - dependencies in R code
  - S3 generic/method consistency
  
* documentation
  - Rd/help files
  - Rd file metadata
  - examples
  - undocumented function arguments
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- _**Unit Tests**_

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Unit Tests

* vital part of package development

* helps ensure future updates don't break functioning code

* easily implemented with the {testthat} package

* all unit tests are run each time the package is checked

--

.pull-left[
```
&gt; usethis::use_testthat()
✔ Setting active project to '~/myPackage'
✔ Adding 'testthat' to 
  Suggests field in DESCRIPTION
✔ Creating 'tests/testthat/'
✔ Writing 'tests/testthat.R'

&gt; usethis::use_test("df_mean")
✔ Writing 'tests/testthat/test-df_mean.R'
● Modify 'tests/testthat/test-df_mean.R'
```
]
.pull-right[
**tests/testthat/test-df_mean.R**
```
context("test-df_mean")

test_that("multiplication works", {
  expect_equal(2 * 2, 4)
})
```
]

---
# Unit Tests

There are many types of checks that can be included
.pull-left[
* `expect_lte() `
* `expect_gte()`
* `expect_equal() `
* `expect_setequal() `
* `expect_equivalent() `
* `expect_identical() `
]
.pull-right[
* `expect_length()`
* `expect_null()`
* `expect_error() `
* `expect_warning()`
* `expect_true()`
]

Each test should 
1. have an informative name  
1. cover a single unit of functionality

The idea is that when a test fails, you’ll know what’s wrong and where in your code to look for the problem.

Hadley Wickham's book on writing R packages provides a thorough review on writing unit tests. 

http://r-pkgs.had.co.nz/tests.html

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- _**Advanced Setup**_
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Advanced Setup
.pull-left[
- _**software license**_

- `usethis::use_news_md()`

- `usethis::use_spell_check()`

- continuous integration

- `usethis::use_coverage()`
]
.pull-right[
Specify the license you want associated with your package.

- `usethis::use_mit_license()`
- `usethis::use_gpl3_license()`
- `usethis::use_lgpl_license()`
- `usethis::use_apl2_license()`
- `usethis::use_cc0_license()`

```
&gt; usethis::use_mit_license("Daniel D. Sjoberg")
✔ Setting License field in DESCRIPTION 
     to 'MIT + file LICENSE'
✔ Writing 'LICENSE.md'
✔ Adding '^LICENSE\\.md$' to '.Rbuildignore'
✔ Writing 'LICENSE'
```
]

---
# Advanced Setup
.pull-left[
- software license

- _**`usethis::use_news_md()`**_

- `usethis::use_spell_check()`

- continuous integration

- `usethis::use_coverage()`
]
.pull-right[
- creates a basic `NEWS.md` in the root directory

- keep track of updates and versions

- communicate changes to API to users (also future you)

```
&gt; usethis::use_news_md()
✔ Writing 'NEWS.md'
● Modify 'NEWS.md'
```
]

---
# Advanced Setup
.pull-left[
- software license

- `usethis::use_news_md()`

- _**`usethis::use_spell_check()`**_

- continuous integration

- `usethis::use_coverage()`
]
.pull-right[
- adds a unit test to automatically run a spell check on documentation and vignettes

- adds a WORDLIST file to the package, which is a dictionary of white-listed words

- runs when the package checks are run

- suggest including `error = TRUE` option so spelling errors fail package checks

```
&gt; usethis::use_spell_check(error = TRUE)
Updated ~/myPackage/tests/spelling.R
● Run `devtools::check()` to trigger spell check
```
]

---
# Advanced Setup
.pull-left[
- software license

- `usethis::use_news_md()`

- `usethis::use_spell_check()`

- _**continuous integration**_

- `usethis::use_coverage()`
]
.pull-right[
- get cool badges

- others more confident in your package

- `usethis::use_travis()` tests build on Linux: http://travis-ci.org

- `usethis::use_appveyor()` tests build on Windows: https://www.appveyor.com/

- tests are triggered each time package is pushed to GitHub

- blog post about using CI https://juliasilge.com/blog/beginners-guide-to-travis/

- requires public GitHub repo
]
&lt;img src="images/travis badge.svg" width = "21%"&gt;
&lt;img src="images/appveyor badge.svg" width = "24.7%"&gt;

---
# Advanced Setup
.pull-left[
- software license

- `usethis::use_news_md()`

- `usethis::use_spell_check()`

- _**continuous integration**_

- `usethis::use_coverage()`
]
.pull-right[
Be sure to follow all directions!
```
&gt; usethis::use_travis()
✔ Writing '.travis.yml'
✔ Adding '^\\.travis\\.yml$' to '.Rbuildignore'
● Turn on travis for your repo at 
    https://travis-ci.org/profile/ddsjoberg
● Add a Travis build status badge by adding 
    the following line to your README:
Copying code to clipboard:
  [![Travis build status](https://travis-ci.org/ddsjoberg/myPackage.svg?branch=master)](https://travis-ci.org/ddsjoberg/myPackage)
  
&gt; usethis::use_appveyor()
✔ Writing 'appveyor.yml'
✔ Adding '^appveyor\\.yml$' to '.Rbuildignore'
● Turn on AppVeyor for this repo at 
    https://ci.appveyor.com/projects/new
● Add a AppVeyor build status badge by adding 
    the following line to your README:
Copying code to clipboard:
  [![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/ddsjoberg/myPackage?branch=master&amp;svg=true)](https://ci.appveyor.com/project/ddsjoberg/myPackage)
```
]

---
# Advanced Setup
.pull-left[
- software license

- `usethis::use_news_md()`

- `usethis::use_spell_check()`

- continuous integration

- _**`usethis::use_coverage()`**_
]
.pull-right[
- more cool badges

- adds test coverage reports to a package that is already using Travis CI

- reports the proportion of code covered by unit tests

- provides reports of coverage of every file, line-by-line

- https://codecov.io/

&lt;img src="images/codecov badge.svg" width = "50%"&gt;
]
&lt;img src="images/codecov_figure_3.png" width = "25%"&gt;

---
# Advanced Setup
.pull-left[
- software license

- `usethis::use_news_md()`

- `usethis::use_spell_check()`

- continuous integration

- _**`usethis::use_coverage()`**_
]
.pull-right[
{usethis} prints directions into the console...be sure to follow them! 
```
&gt; usethis::use_coverage()
✔ Adding 'covr' to Suggests field in DESCRIPTION
✔ Writing 'codecov.yml'
✔ Adding '^codecov\\.yml$' to '.Rbuildignore'
● Add a Coverage status badge by adding the 
    following line to your README:
Copying code to clipboard:
  \[\!\[Coverage status\](https://codecov.io/gh/ddsjoberg/myPackage/branch/master/graph/badge.svg)\](https://codecov.io/github/ddsjoberg/myPackage?branch=master)
● Add to '.travis.yml':
Copying code to clipboard:
  after_success:
    \- Rscript -e 'covr::codecov()'
```
]
&lt;img src="images/codecov figure 2.png" width = "25%"&gt;

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- _**Advanced Documentation**_

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Advanced Documentation: README

.pull-left[
- GitHub renders the README file and is often the first thing users will see about your package

- rather than use a basic README.md, use an R markdown README.rmd

- `usethis::use_readme_rmd()`
```
&gt; usethis::use_readme_rmd()
✔ Writing 'README.Rmd'
✔ Adding '^README\\.Rmd$' to '.Rbuildignore'
● Modify 'README.Rmd'
✔ Writing '.git/hooks/pre-commit'
```
]
.pull-right[
- update and knit README.rmd, and it'll create README.md
  - README.md now has this header:       
  `&lt;!-- README.md is generated from README.Rmd. Please edit that file --&gt;`

- be sure to knit README.rmd after you modify the file OR update functions highlighted in the README file
]

---
# Advanced Documentation: Vignettes

.pull-left[
- a vignette is a long-form guide to your package

- describes the problem your package is designed to solve, then shows the reader how to solve it

```
&gt; usethis::use_vignette("my first vignette")
#&gt; ✔ Adding 'knitr' to Suggests field in DESCRIPTION
#&gt; ✔ Setting VignetteBuilder field in 
#&gt;     DESCRIPTION to 'knitr'
#&gt; ✔ Adding 'rmarkdown' to Suggests field 
#&gt;     in DESCRIPTION
#&gt; ✔ Creating 'vignettes/'
#&gt; ✔ Adding '*.html', '*.R' to 'vignettes/.gitignore'
#&gt; ✔ Adding 'inst/doc' to '.gitignore'
#&gt; ✔ Creating 'vignettes/my-first-vignette.Rmd'
#&gt; ● Modify 'vignettes/my-first-vignette.Rmd'
```
]
--
.pull-right[
- a vignette is an R markdown document with HTML output

- be sure to change the title in BOTH `title:` and `VignetteIndexEntry{}` in the vignette yaml
```
title: "Vignette Title"
author: "Vignette Author"
date: "2019-04-01"
output: rmarkdown::html_vignette
vignette: &gt;
  %\VignetteIndexEntry{Vignette Title}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
```

- R packages, Vignettes Chapter: http://r-pkgs.had.co.nz/vignettes.html
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- _**Include Datasets**_

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Include Datasets

.pull-left[
- including datasets in an R package is easy with `use_data_raw()` and `use_data()`

- we'll go over an example where we simulate a dataset and save it in the package


```r
&gt; usethis::use_data_raw()
#&gt; ✔ Creating 'data-raw/'
#&gt; ✔ Adding '^data-raw$' to '.Rbuildignore'
#&gt; Next:
#&gt; ● Add data creation scripts 
#&gt;    in 'data-raw/'
#&gt; ● Use `usethis::use_data()` to 
#&gt;    add data to package
```
]
--
.pull-right[
- simulate dataset, and `use_data()` will save it with the package

- save this script is the `data-raw/` folder


```r
set.seed(8976) # remeber to set your seed!
my_data &lt;-
  tibble::tibble(
    x = runif(100),
    y = runif(100)
  )

usethis::use_data(my_data, overwrite = TRUE)
#&gt; ✔ Creating 'data/'
#&gt; ✔ Saving 'my_data' to 'data/my_data.rda'
```

]

---
# Include Datasets

.pull-left[
- document the dataset

- use {roxygen2} comments for documentation

- add a file to the R folder to begin documenting

- I call mine `data.R`
```
&gt; usethis::use_r("data")
● Modify 'R/data.R'
```
]
--
.pull-right[
`R/data.R`
```
#' My simulated data
#'
#' A simulated dataset that I am saving in my package.
#'
#' @format A data frame with 100 rows
#' \describe{
#'     \item{x}{Random Uniform Variable}
#'     \item{y}{Random Uniform Variable}
#' }
"my_data"
```
- after you write the {roxygen2} comments, document the package

- the help file will be accessible with `?my_data` after the package has been loaded
]

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- _**Other Tips**_

- Non-Standard Evaluation 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Other Tips

- {roxygen2} tags `@import` and `@importFrom`

- `use_pipe()` to import and export {magrittr} pipe operator

- helper functions for tidy development

---
# Other Tips: Import

- there are a few functions from the tidyverse we use frequently

- referring to them with `::` quickly becomes cumbersome

- we can import functions and even entire packages to avoid the `::` notation

- {roxygen2} tags `@import` and `@importFrom`

---
# Other Tips: Import
.pull-left[
- remember that boring package-level documentation file we made with `use_package_doc()`? let's use this file to import commonly used functions

```
#' @import dplyr
#' @import purrr
#' @importFrom tidyr nest unnest 
     spread gather complete
#' @importFrom tibble tibble as_tibble
#' @importFrom rlang .data %||% set_names sym 
     expr enexpr quo enquo parse_expr
#' @importFrom glue glue
#' @keywords internal
"_PACKAGE"

# allowing for the use of the dot when piping
utils::globalVariables(".")
```
]
.pull-right[
- when adding entire package imports, be sure to run the package checks. you may experience warnings from conflicting function names 
  - this is common with tidyverse packages as many of them contain the same functions
  
- `@import` and `@importFrom` can be placed in any R code file
  - can import same function in multiple files. {roxygen2} will sort out duplicates when the package is documented

- use the package-level documentation file for imports that apply to all functions in your package
]
???
mention that generally it's best practice to use `::` notation.  but readability of your code is more important and if importing functions improves readability then do it.

also discuss the global variables issue and why the last line is included

---
# Other Tips: the pipe

.pull-left[
- the {magrittr} pipe operator is so useful, you may want to both import and export it to make it available to users of your package

```
&gt; usethis::use_pipe()
✔ Adding 'magrittr' to Imports 
    field in DESCRIPTION
✔ Writing 'R/utils-pipe.R'
● Run `devtools::document()`
```
]
.pull-right[
`R/utils-pipe.R`
```
#' Pipe operator
#'
#' See \code{magrittr::\link[magrittr]{\%&gt;\%}} 
#' for details.
#'
#' @name %&gt;%
#' @rdname pipe
#' @keywords internal
#' @export
#' @importFrom magrittr %&gt;%
#' @usage lhs \%&gt;\% rhs
NULL
```
]

---
# Other Tips: tidy helpers

the {usethis} package contains helper functions to develop tidy packages

these are my favorites

- `use_tidy_description()`
  - puts fields in standard order and alphabetizes dependencies in DESCRIPTION file

- `use_tidy_versions(overwrite = FALSE)`
  - pins all dependencies to require at least the currently installed version
  - helps ensure your package will work on all systems

- `use_tidy_style(strict = TRUE)`
  - uses the {styler} package to style all code according to the tidyverse style guide
  - keeps your code easy to read, looking good, and collaborative


---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- _**Non-Standard Evaluation**_ 

- Collaborate with GitHub

- Create Package Website
]
]

---
# Non-Standard Evaluation

- tidyverse code is quick to write, but as a result it is ambiguous
  - these equivalent `mutate` statements return different results
  - the code in your package must be precise
  
.pull-left[

```r
y = 10
tibble(
  x = 1:4
) %&gt;%
* mutate(
*   xy = x + y
* )
```

```
## # A tibble: 4 x 2
##       x    xy
##   &lt;int&gt; &lt;dbl&gt;
## 1     1    11
## 2     2    12
## 3     3    13
## 4     4    14
```
]
.pull-right[

```r
tibble(
  y = 4:1,
  x = 1:4
) %&gt;%
* mutate(
*   xy = x + y
* )
```

```
## # A tibble: 4 x 3
##       y     x    xy
##   &lt;int&gt; &lt;int&gt; &lt;int&gt;
## 1     4     1     5
## 2     3     2     5
## 3     2     3     5
## 4     1     4     5
```
]

---
# Non-Standard Evaluation

- how to make the code precise?
 - import the `.data` function from {rlang}
 - use `.data$&lt;varname&gt;` EVERY time you reference a column within a `mutate` statement
 - if you don't use `.data`, the package check will return a warning

.pull-left[

```r
y = 10
tibble(
  x = 1:4
) %&gt;%
* mutate(
*   xy = .data$x + y
* )
```

```
## # A tibble: 4 x 2
##       x    xy
##   &lt;int&gt; &lt;dbl&gt;
## 1     1    11
## 2     2    12
## 3     3    13
## 4     4    14
```
]
.pull-right[

```r
tibble(
  y = 4:1,
  x = 1:4
) %&gt;%
* mutate(
*   xy = .data$x + .data$y
* )
```

```
## # A tibble: 4 x 3
##       y     x    xy
##   &lt;int&gt; &lt;int&gt; &lt;int&gt;
## 1     4     1     5
## 2     3     2     5
## 3     2     3     5
## 4     1     4     5
```
]

---
# Non-Standard Evaluation

- other tidyverse functions take bare column names as inputs
  - e.g. `mtcars %&gt;% select(mpg, hp)`
  - the reference to the `mpg` and `hp` columns is not standard, and the package check will return warnings if this code is found
- many tidyverse functions will allow you to simply replace the bare references with quoted strings

.pull-left[

```r
mtcars %&gt;% select(mpg, hp)

mtcars %&gt;% pull(mpg)

mtcars %&gt;% group_by(cyl) %&gt;% 
  nest(mpg, hp)
```
]
.pull-right[

```r
mtcars %&gt;% select(c("mpg", "hp"))

mtcars %&gt;% pull("mpg")

mtcars %&gt;% group_by(cyl) %&gt;% 
  nest(c("mpg", "hp"))
```
]


???
group_by is NOT one of these functions!

---
# Non-Standard Evaluation

- for functions that do not allow you to simply add a string, use `!!` and `rlang::sym()`
- when you have multiple variables, use `!!!` and `rlang::syms()` instead of `!!` and `rlang::sym()` 

.pull-left[

```r
mtcars %&gt;% group_by(cyl)


mtcars %&gt;% group_by(cyl, am)
```
]
.pull-right[

```r
mtcars %&gt;% group_by(!!sym("cyl"))
mtcars %&gt;% group_by(.data$cyl)

by_vars &lt;- c("cyl", "am")
mtcars %&gt;% group_by(!!!syms(by_vars))
mtcars %&gt;% group_by(.data$cyl, .data$am)
```
]

---
# Non-Standard Evaluation

- entire expressions can be stored as string and evaluated 

- this is particularly powerful when combined with the {glue} package

.pull-left[

```r
mtcars %&gt;% filter(cyl == 4)
```
]
.pull-right[

```r
mtcars %&gt;% filter(!!parse_expr("cyl == 4"))
mtcars %&gt;% filter(.data$cyl == 4)
```
]

- can also create functions with NSE inputs

- briefly, you replace `sym()` with `enquo()`, more on that in the additional reading

- additional resources
  - *Programming with dplyr*  
  https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html
  
  - *Tidy evaluation, most common actions*  
  https://edwinth.github.io/blog/dplyr-recipes/
      - this resource is excellent!

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- _**Collaborate with GitHub**_

- Create Package Website
]
]

---
# Collaborate with GitHub

- create a development branch (e.g. *dev*) and do 100% of your initial package building directly on this branch

- once package is standing on its own legs (not necessarily done), make all updates via forks or feature branches

- protect your *master* and *dev* branches
  - from the GitHub repo, select *Settings*, select *Branches*, and add rules for each branch
  
  - for the *dev* and  *master* branches, I recommend 
  
      - "Require pull request reviews before merging" 
      
      - "Require status checks to pass before merging" 
      
      - "Include administrators"

---
class: inverse
# Outline
.xlarge[
.pull-left[
- R Package Structure

- Getting Started

- Adding Functions

- Build your Package

- Unit Tests

- Advanced Setup
]
.pull-right[
- Advanced Documentation

- Include Datasets

- Other Tips

- Non-Standard Evaluation 

- Collaborate with GitHub

- _**Create Package Website**_
]
]

---
# Create Package Website

- lastly, it's easy to create a website for your package

- easier for a user to navigate, find functions, and 

- from the GitHub repo, select *Settings*, scroll down to *GitHub Pages*, from the *Source* menu select *master branch/docs folder*

- the location of the published site is listed under *GitHub Pages*

- run `pkgdown::build_site()`

- done! can take a few minutes to be available online

- more details at https://pkgdown.r-lib.org/

---
# Resources

.pull-left[
- {roxygen2}
  - *Rd* vignette in {roxygen2} package
  - Broman Blog https://tinyurl.com/yxj2vzkn
  - RStudio Blog https://tinyurl.com/yyrvysoy
  
- continuous integration
  - Silge Blog https://tinyurl.com/y2b6pxne

- *R Packages*, by Hadley Wickham
  - touches on most of the topics covered here (package structures, unit tests, documentation)
  - does not include {usethis} setup
  - http://r-pkgs.had.co.nz/
  
- Git and GitHub
  - https://happygitwithr.com/
]
.pull-right[
&lt;img src="images/R Packages cover.png" width="80%"&gt;
]

---
class: center, middle
background-image: url(images/hex_stickers_blurred3.png)
background-size: contain

# Thank you

&lt;img src = "images/slide_show_icon.png" width="2.4%" height="2.4%"&gt; slides at &lt;a href="http://www.danieldsjoberg.com/writing-R-packages"&gt;danieldsjoberg.com/writing-R-packages&lt;/a&gt;  
&lt;img src = "images/github_icon.png" width="2.4%" height="2.4%"&gt; source code* at &lt;a href="https://github.com/ddsjoberg/writing-R-packages"&gt;github.com/ddsjoberg/writing-R-packages&lt;/a&gt;

.footnote[.small[\* has the code for the package we built here]]
    </textarea>
<style data-target="print-only">@media screen {.remark-slide-container{display:block;}.remark-slide-scaler{box-shadow:none;}}</style>
<script src="https://remarkjs.com/downloads/remark-latest.min.js"></script>
<script>var slideshow = remark.create({
"ratio": "16:9",
"highlightStyle": "github",
"highlightLines": true,
"countIncrementalSlides": false
});
if (window.HTMLWidgets) slideshow.on('afterShowSlide', function (slide) {
  window.dispatchEvent(new Event('resize'));
});
(function(d) {
  var s = d.createElement("style"), r = d.querySelector(".remark-slide-scaler");
  if (!r) return;
  s.type = "text/css"; s.innerHTML = "@page {size: " + r.style.width + " " + r.style.height +"; }";
  d.head.appendChild(s);
})(document);

(function(d) {
  var el = d.getElementsByClassName("remark-slides-area");
  if (!el) return;
  var slide, slides = slideshow.getSlides(), els = el[0].children;
  for (var i = 1; i < slides.length; i++) {
    slide = slides[i];
    if (slide.properties.continued === "true" || slide.properties.count === "false") {
      els[i - 1].className += ' has-continuation';
    }
  }
  var s = d.createElement("style");
  s.type = "text/css"; s.innerHTML = "@media print { .has-continuation { display: none; } }";
  d.head.appendChild(s);
})(document);
// delete the temporary CSS (for displaying all slides initially) when the user
// starts to view slides
(function() {
  var deleted = false;
  slideshow.on('beforeShowSlide', function(slide) {
    if (deleted) return;
    var sheets = document.styleSheets, node;
    for (var i = 0; i < sheets.length; i++) {
      node = sheets[i].ownerNode;
      if (node.dataset["target"] !== "print-only") continue;
      node.parentNode.removeChild(node);
    }
    deleted = true;
  });
})();</script>

<script>
(function() {
  var links = document.getElementsByTagName('a');
  for (var i = 0; i < links.length; i++) {
    if (/^(https?:)?\/\//.test(links[i].getAttribute('href'))) {
      links[i].target = '_blank';
    }
  }
})();
</script>

<script>
slideshow._releaseMath = function(el) {
  var i, text, code, codes = el.getElementsByTagName('code');
  for (i = 0; i < codes.length;) {
    code = codes[i];
    if (code.parentNode.tagName !== 'PRE' && code.childElementCount === 0) {
      text = code.textContent;
      if (/^\\\((.|\s)+\\\)$/.test(text) || /^\\\[(.|\s)+\\\]$/.test(text) ||
          /^\$\$(.|\s)+\$\$$/.test(text) ||
          /^\\begin\{([^}]+)\}(.|\s)+\\end\{[^}]+\}$/.test(text)) {
        code.outerHTML = code.innerHTML;  // remove <code></code>
        continue;
      }
    }
    i++;
  }
};
slideshow._releaseMath(document);
</script>
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src  = 'https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML';
  if (location.protocol !== 'file:' && /^https?:/.test(script.src))
    script.src  = script.src.replace(/^https?:/, '');
  document.getElementsByTagName('head')[0].appendChild(script);
})();
</script>
  </body>
</html>
